﻿#region << 版 本 注 释 >>
/*----------------------------------------------------------------
// Copyright (C) 2021 kingerrobot
// 版权所有。 
//
// 文件名：IRcsLocation
// 文件功能描述：
//
// 创建者：名字 (zzl)
// 时间：2021/12/7 16:25:32
//
// 修改人：
// 时间：
// 修改说明：
// 版本：V1.0.0
//----------------------------------------------------------------*/
#endregion
using KingerRobot.MexicoSailunMDC.Dao;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;

namespace KingerRobot.MexicoSailunMDC.SpiService;
internal class BRcsLocation : IRcsLocation
{
    private readonly static IWcsLocSku _WcsLocSku = new BWcsLocSku();
    private readonly static IProdSku _ProdSku = new BProdSku();
    private readonly static IProdProduct _ProdProduct = new BProdProduct();
    private readonly static IWcsEquipLocHold _WcsEquipLocHold = new BWcsEquipLocHold();
    private readonly static ITask _Task = new BTask();
    private readonly static IWcsAsrsLocHalt _WcsAsrsLocHalt = new BWcsAsrsLocHalt();
    private readonly static IProdMaterial _ProdMaterial = new BProdMaterial();
    private readonly static IWmsSetting _WmsSetting = new BWmsSetting();




    public int UpdateLocUnEnable(long id, int taskNo = 0)
    {
        var db = Db.Default;
        var dateTime = DateTime.Now;
        var result = 0;
        result = db.RcsLocations.Where(t => t.Id == id).Update(new PORcsLocation
        {
            LocEnable = 0,
            UpdateTime = dateTime,
            Remarks = $"手工删除任务{taskNo},{dateTime}"
        });
        return db.SaveChanges();
    }

    public int ChangeLocEnable(long id, string remark)
    {
        var db = Db.Default;
        var dateTime = DateTime.Now;
        var result = 0;

        result = db.RcsLocations.Where(t => t.Id == id).Update(new PORcsLocation
        {
            LocEnable = 0,
            UpdateTime = dateTime,
            Remarks = remark
        });

        return db.SaveChanges();
    }
    public List<PORcsLocation> GetAllLocations()
    {
        var db = Db.Default;
        var result = db.RcsLocations
            .Where(t => t.UseFlag == 1 && t.LocEnable == 1
            && t.ErrInHas == 0
            && t.ErrOutEmpty == 0).AsNoTracking().Select(t => new PORcsLocation()
            {
                Id = t.Id,
                LocCode = t.LocCode,
                LocName = t.LocName,
                PlcCode = t.PlcCode,
                LocType = t.LocType,
                GroupId = t.GroupId,
                GroupIndex = t.GroupIndex,
                AxisX = t.AxisX,
                AxisY = t.AxisY,
                AxisZ = t.AxisZ,
                AxisT = t.AxisT,
                NAxisX = t.NAxisX,
                NAxisY = t.NAxisY,
                NAxisZ = t.NAxisZ,
                NAxisT = t.NAxisT,
                LocHasSku = t.LocHasSku,
                LocHasSkuTime = t.LocHasSkuTime,
                TaskId = t.TaskId,
                TaskOccupy = t.TaskOccupy,
                TaskOccupyTime = t.TaskOccupyTime,
                LocEnable = t.LocEnable,
                InEnable = t.InEnable,
                OutEnable = t.OutEnable,
                MaterialId = t.MaterialId,
                ProductCode = t.ProductCode,
                MdTime = t.MdTime,
                ErrOutEmpty = t.ErrOutEmpty,
                ErrInHas = t.ErrInHas,
                UpdateTime = t.UpdateTime,
                UseFlag = t.UseFlag,
                LocHeight = t.LocHeight,
                LocMinOutsize = t.LocMinOutsize,
                LocMaxOutsize = t.LocMaxOutsize,
                LocTireType = t.LocTireType,
                RelateScore = t.RelateScore,
                CuringGroup = t.CuringGroup,
                CrnId = t.CrnId,
                LocInputType = t.LocInputType
            })
            .ToList();
        return result;
    }

    public List<PORcsLocation> GetAllCuringLocations()
    {
        var db = Db.Default;
        var result = db.RcsLocations
            .Where(t => t.UseFlag == 1 && t.LocEnable == 1
            && t.ErrInHas == 0
            && t.ErrOutEmpty == 0
            && t.LocType == (int)EnumLocType.Curing
            ).AsNoTracking()
            .Select(t => new PORcsLocation()
            {
                Id = t.Id,
                LocCode = t.LocCode,
                LocName = t.LocName,
                PlcCode = t.PlcCode,
                LocType = t.LocType,
                GroupId = t.GroupId,
                GroupIndex = t.GroupIndex,
                AxisX = t.AxisX,
                AxisY = t.AxisY,
                AxisZ = t.AxisZ,
                AxisT = t.AxisT,
                NAxisX = t.NAxisX,
                NAxisY = t.NAxisY,
                NAxisZ = t.NAxisZ,
                NAxisT = t.NAxisT,
                LocHasSku = t.LocHasSku,
                LocHasSkuTime = t.LocHasSkuTime,
                TaskId = t.TaskId,
                TaskOccupy = t.TaskOccupy,
                TaskOccupyTime = t.TaskOccupyTime,
                LocEnable = t.LocEnable,
                InEnable = t.InEnable,
                OutEnable = t.OutEnable,
                MaterialId = t.MaterialId,
                ProductCode = t.ProductCode,
                MdTime = t.MdTime,
                ErrOutEmpty = t.ErrOutEmpty,
                ErrInHas = t.ErrInHas,
                UpdateTime = t.UpdateTime,
                UseFlag = t.UseFlag,
                LocHeight = t.LocHeight,
                LocMinOutsize = t.LocMinOutsize,
                LocMaxOutsize = t.LocMaxOutsize,
                LocTireType = t.LocTireType,
                RelateScore = t.RelateScore,
                CuringGroup = t.CuringGroup,
                CrnId = t.CrnId,
                LocInputType = t.LocInputType
            })
            .ToList();
        return result;
    }

    public List<PORcsLocation> GetAllLocationsISLoc()
    {
        var db = Db.Default;
        var result = db.RcsLocations
            .Where(t => t.UseFlag == 1 && t.LocEnable == 1 && t.LocType == (int)EnumLocType.Location
            && t.ErrInHas == 0
            && t.ErrOutEmpty == 0).AsNoTracking()
            .Select(t => new PORcsLocation()
            {
                Id = t.Id,
                LocCode = t.LocCode,
                LocName = t.LocName,
                PlcCode = t.PlcCode,
                LocType = t.LocType,
                GroupId = t.GroupId,
                GroupIndex = t.GroupIndex,
                AxisX = t.AxisX,
                AxisY = t.AxisY,
                AxisZ = t.AxisZ,
                AxisT = t.AxisT,
                NAxisX = t.NAxisX,
                NAxisY = t.NAxisY,
                NAxisZ = t.NAxisZ,
                NAxisT = t.NAxisT,
                LocHasSku = t.LocHasSku,
                LocHasSkuTime = t.LocHasSkuTime,
                TaskId = t.TaskId,
                TaskOccupy = t.TaskOccupy,
                TaskOccupyTime = t.TaskOccupyTime,
                LocEnable = t.LocEnable,
                InEnable = t.InEnable,
                OutEnable = t.OutEnable,
                MaterialId = t.MaterialId,
                ProductCode = t.ProductCode,
                MdTime = t.MdTime,
                ErrOutEmpty = t.ErrOutEmpty,
                ErrInHas = t.ErrInHas,
                UpdateTime = t.UpdateTime,
                UseFlag = t.UseFlag,
                LocHeight = t.LocHeight,
                LocMinOutsize = t.LocMinOutsize,
                LocMaxOutsize = t.LocMaxOutsize,
                LocTireType = t.LocTireType,
                RelateScore = t.RelateScore,
                CuringGroup = t.CuringGroup,
                CrnId = t.CrnId,
                LocInputType = t.LocInputType
            })
            .ToList();
        return result;
    }
    //TODO 测试
    public List<PORcsLocation> GetAllLocationsOutISLoc()
    {
        var db = Db.Default;
        var result = db.RcsLocations
            .Where(t => t.UseFlag == 1 && t.LocEnable == 1 && t.LocType == (int)EnumLocType.Location
            && t.ErrInHas == 0
            && t.ErrOutEmpty == 0).Select(t => new PORcsLocation()
            {
                Id = t.Id,
                LocCode = t.LocCode,
                LocName = t.LocName,
                PlcCode = t.PlcCode,
                LocType = t.LocType,
                GroupId = t.GroupId,
                GroupIndex = t.GroupIndex,
                AxisX = t.AxisX,
                AxisY = t.AxisY,
                AxisZ = t.AxisZ,
                AxisT = t.AxisT,
                NAxisX = t.NAxisX,
                NAxisY = t.NAxisY,
                NAxisZ = t.NAxisZ,
                NAxisT = t.NAxisT,
                LocHasSku = t.LocHasSku,
                LocHasSkuTime = t.LocHasSkuTime,
                TaskId = t.TaskId,
                TaskOccupy = t.TaskOccupy,
                TaskOccupyTime = t.TaskOccupyTime,
                LocEnable = t.LocEnable,
                InEnable = t.InEnable,
                OutEnable = t.OutEnable,
                MaterialId = t.MaterialId,
                ProductCode = t.ProductCode,
                MdTime = t.MdTime,
                ErrOutEmpty = t.ErrOutEmpty,
                ErrInHas = t.ErrInHas,
                UpdateTime = t.UpdateTime,
                UseFlag = t.UseFlag,
                LocHeight = t.LocHeight,
                LocMinOutsize = t.LocMinOutsize,
                LocMaxOutsize = t.LocMaxOutsize,
                LocTireType = t.LocTireType,
                RelateScore = t.RelateScore,
                CuringGroup = t.CuringGroup,
                CrnId = t.CrnId,
                LocInputType = t.LocInputType

            }).AsNoTracking()
            .ToList();
        return result;
    }
    public List<PORcsLocation> GetAllNoHaveHighLocationsISLoc()
    {
        var db = Db.Default;
        _ = decimal.TryParse(_WmsSetting.GetWmsSettingByCode(ConstFields.MaterialHeightSideType).Value, out var settingHigh);
        var result = db.RcsLocations
            .Where(t => t.UseFlag == 1
            && t.LocEnable == 1
            && t.LocType == (int)EnumLocType.Location
            && t.ErrInHas == 0
            && t.ErrOutEmpty == 0
            && t.InEnable == 1
            && t.LocHeight > settingHigh
            && t.LocHasSku ==1  //更改为1 获取有货的数据
            ).AsNoTracking()
            .Select(t => new PORcsLocation()
            {
                Id = t.Id,
                LocCode = t.LocCode,
                LocName = t.LocName,
                PlcCode = t.PlcCode,
                LocType = t.LocType,
                GroupId = t.GroupId,
                GroupIndex = t.GroupIndex,
                AxisX = t.AxisX,
                AxisY = t.AxisY,
                AxisZ = t.AxisZ,
                AxisT = t.AxisT,
                NAxisX = t.NAxisX,
                NAxisY = t.NAxisY,
                NAxisZ = t.NAxisZ,
                NAxisT = t.NAxisT,
                LocHasSku = t.LocHasSku,
                LocHasSkuTime = t.LocHasSkuTime,
                TaskId = t.TaskId,
                TaskOccupy = t.TaskOccupy,
                TaskOccupyTime = t.TaskOccupyTime,
                LocEnable = t.LocEnable,
                InEnable = t.InEnable,
                OutEnable = t.OutEnable,
                MaterialId = t.MaterialId,
                ProductCode = t.ProductCode,
                MdTime = t.MdTime,
                ErrOutEmpty = t.ErrOutEmpty,
                ErrInHas = t.ErrInHas,
                UpdateTime = t.UpdateTime,
                UseFlag = t.UseFlag,
                LocHeight = t.LocHeight,
                LocMinOutsize = t.LocMinOutsize,
                LocMaxOutsize = t.LocMaxOutsize,
                LocTireType = t.LocTireType,
                RelateScore = t.RelateScore,
                CuringGroup = t.CuringGroup,
                CrnId = t.CrnId,
                LocInputType = t.LocInputType
            })
            .ToList();
        return result;
    }
    public List<PORcsLocation> GetAllNoHasLocationsISLoc()
    {
        var db = Db.Default;
        var result = db.RcsLocations
            .Where(t => t.UseFlag == 1 && t.LocEnable == 1 && t.LocType == (int)EnumLocType.Location
            && t.ErrInHas == 0
            && t.ErrOutEmpty == 0
            && t.LocHasSku == 0
            ).AsNoTracking()
            .Select(t => new PORcsLocation()
            {
                Id = t.Id,
                LocCode = t.LocCode,
                LocName = t.LocName,
                PlcCode = t.PlcCode,
                LocType = t.LocType,
                GroupId = t.GroupId,
                GroupIndex = t.GroupIndex,
                AxisX = t.AxisX,
                AxisY = t.AxisY,
                AxisZ = t.AxisZ,
                AxisT = t.AxisT,
                NAxisX = t.NAxisX,
                NAxisY = t.NAxisY,
                NAxisZ = t.NAxisZ,
                NAxisT = t.NAxisT,
                LocHasSku = t.LocHasSku,
                LocHasSkuTime = t.LocHasSkuTime,
                TaskId = t.TaskId,
                TaskOccupy = t.TaskOccupy,
                TaskOccupyTime = t.TaskOccupyTime,
                LocEnable = t.LocEnable,
                InEnable = t.InEnable,
                OutEnable = t.OutEnable,
                MaterialId = t.MaterialId,
                ProductCode = t.ProductCode,
                MdTime = t.MdTime,
                ErrOutEmpty = t.ErrOutEmpty,
                ErrInHas = t.ErrInHas,
                UpdateTime = t.UpdateTime,
                UseFlag = t.UseFlag,
                LocHeight = t.LocHeight,
                LocMinOutsize = t.LocMinOutsize,
                LocMaxOutsize = t.LocMaxOutsize,
                LocTireType = t.LocTireType,
                RelateScore = t.RelateScore,
                CuringGroup = t.CuringGroup,
                CrnId = t.CrnId,
                LocInputType = t.LocInputType
            })
            .ToList();
        return result;
    }


    public List<PORcsLocation> GetAllLocationsByType(int type)
    {
        var db = Db.Default;
        var result = db.RcsLocations
            .Where(t => t.UseFlag == 1 && t.LocType == type).AsNoTracking()
            .Select(t => new PORcsLocation()
            {
                Id = t.Id,
                LocCode = t.LocCode,
                LocName = t.LocName,
                PlcCode = t.PlcCode,
                LocType = t.LocType,
                GroupId = t.GroupId,
                GroupIndex = t.GroupIndex,
                AxisX = t.AxisX,
                AxisY = t.AxisY,
                AxisZ = t.AxisZ,
                AxisT = t.AxisT,
                NAxisX = t.NAxisX,
                NAxisY = t.NAxisY,
                NAxisZ = t.NAxisZ,
                NAxisT = t.NAxisT,
                LocHasSku = t.LocHasSku,
                LocHasSkuTime = t.LocHasSkuTime,
                TaskId = t.TaskId,
                TaskOccupy = t.TaskOccupy,
                TaskOccupyTime = t.TaskOccupyTime,
                LocEnable = t.LocEnable,
                InEnable = t.InEnable,
                OutEnable = t.OutEnable,
                MaterialId = t.MaterialId,
                ProductCode = t.ProductCode,
                MdTime = t.MdTime,
                ErrOutEmpty = t.ErrOutEmpty,
                ErrInHas = t.ErrInHas,
                UpdateTime = t.UpdateTime,
                UseFlag = t.UseFlag,
                LocHeight = t.LocHeight,
                LocMinOutsize = t.LocMinOutsize,
                LocMaxOutsize = t.LocMaxOutsize,
                LocTireType = t.LocTireType,
                RelateScore = t.RelateScore,
                CuringGroup = t.CuringGroup,
                CrnId = t.CrnId,
                LocInputType = t.LocInputType
            })
            .ToList();
        return result;
    }
    public List<long> GetAllLocationTaskIdByType(int type)
    {
        var db = Db.Default;
        var result = db.RcsLocations
            .Where(t => t.UseFlag == 1 && t.LocType == type && t.TaskId > 0).Select(t => t.TaskId ?? 0)
            .ToList();
        return result;
    }

    public List<PORcsLocation> GetHasSkuLocationsByType(int type)
    {
        var db = Db.Default;
        var result = db.RcsLocations
            .Where(t => t.UseFlag == 1 && t.LocType == type && t.LocHasSku == 1).Select(t => new PORcsLocation()
            {
                Id = t.Id,
                LocCode = t.LocCode,
                LocName = t.LocName,
                PlcCode = t.PlcCode,
                LocType = t.LocType,
                GroupId = t.GroupId,
                GroupIndex = t.GroupIndex,
                AxisX = t.AxisX,
                AxisY = t.AxisY,
                AxisZ = t.AxisZ,
                AxisT = t.AxisT,
                NAxisX = t.NAxisX,
                NAxisY = t.NAxisY,
                NAxisZ = t.NAxisZ,
                NAxisT = t.NAxisT,
                LocHasSku = t.LocHasSku,
                LocHasSkuTime = t.LocHasSkuTime,
                TaskId = t.TaskId,
                TaskOccupy = t.TaskOccupy,
                TaskOccupyTime = t.TaskOccupyTime,
                LocEnable = t.LocEnable,
                InEnable = t.InEnable,
                OutEnable = t.OutEnable,
                MaterialId = t.MaterialId,
                ProductCode = t.ProductCode,
                MdTime = t.MdTime,
                ErrOutEmpty = t.ErrOutEmpty,
                ErrInHas = t.ErrInHas,
                UpdateTime = t.UpdateTime,
                UseFlag = t.UseFlag,
                LocHeight = t.LocHeight,
                LocMinOutsize = t.LocMinOutsize,
                LocMaxOutsize = t.LocMaxOutsize,
                LocTireType = t.LocTireType,
                RelateScore = t.RelateScore,
                CuringGroup = t.CuringGroup,
                CrnId = t.CrnId,
                LocInputType = t.LocInputType
            })
            .ToList();
        return result;
    }
    public List<PORcsLocation> GetLocations()
    {
        var db = Db.Default;
        var result = db.RcsLocations
           .Select(t => new PORcsLocation()
           {
               Id = t.Id,
               LocCode = t.LocCode,
               LocName = t.LocName,
               PlcCode = t.PlcCode,
               LocType = t.LocType,
               GroupId = t.GroupId,
               GroupIndex = t.GroupIndex,
               AxisX = t.AxisX,
               AxisY = t.AxisY,
               AxisZ = t.AxisZ,
               AxisT = t.AxisT,
               NAxisX = t.NAxisX,
               NAxisY = t.NAxisY,
               NAxisZ = t.NAxisZ,
               NAxisT = t.NAxisT,
               LocHasSku = t.LocHasSku,
               LocHasSkuTime = t.LocHasSkuTime,
               TaskId = t.TaskId,
               TaskOccupy = t.TaskOccupy,
               TaskOccupyTime = t.TaskOccupyTime,
               LocEnable = t.LocEnable,
               InEnable = t.InEnable,
               OutEnable = t.OutEnable,
               MaterialId = t.MaterialId,
               ProductCode = t.ProductCode,
               MdTime = t.MdTime,
               ErrOutEmpty = t.ErrOutEmpty,
               ErrInHas = t.ErrInHas,
               UpdateTime = t.UpdateTime,
               UseFlag = t.UseFlag,
               LocHeight = t.LocHeight,
               LocMinOutsize = t.LocMinOutsize,
               LocMaxOutsize = t.LocMaxOutsize,
               LocTireType = t.LocTireType,
               RelateScore = t.RelateScore,
               CuringGroup = t.CuringGroup,
               CrnId = t.CrnId,
               LocInputType = t.LocInputType
           })
            .ToList();
        return result;
    }
    public List<PORcsLocation> GetAllInNoTaskLocations()
    {
        var db = Db.Default;
        var result = GetAllLocationsISLoc()
            .Where(t => t.InEnable == 1 && t.TaskOccupy == 0)
            .Select(t => new PORcsLocation()
            {
                Id = t.Id,
                LocCode = t.LocCode,
                LocName = t.LocName,
                PlcCode = t.PlcCode,
                LocType = t.LocType,
                GroupId = t.GroupId,
                GroupIndex = t.GroupIndex,
                AxisX = t.AxisX,
                AxisY = t.AxisY,
                AxisZ = t.AxisZ,
                AxisT = t.AxisT,
                NAxisX = t.NAxisX,
                NAxisY = t.NAxisY,
                NAxisZ = t.NAxisZ,
                NAxisT = t.NAxisT,
                LocHasSku = t.LocHasSku,
                LocHasSkuTime = t.LocHasSkuTime,
                TaskId = t.TaskId,
                TaskOccupy = t.TaskOccupy,
                TaskOccupyTime = t.TaskOccupyTime,
                LocEnable = t.LocEnable,
                InEnable = t.InEnable,
                OutEnable = t.OutEnable,
                MaterialId = t.MaterialId,
                ProductCode = t.ProductCode,
                MdTime = t.MdTime,
                ErrOutEmpty = t.ErrOutEmpty,
                ErrInHas = t.ErrInHas,
                UpdateTime = t.UpdateTime,
                UseFlag = t.UseFlag,
                LocHeight = t.LocHeight,
                LocMinOutsize = t.LocMinOutsize,
                LocMaxOutsize = t.LocMaxOutsize,
                LocTireType = t.LocTireType,
                RelateScore = t.RelateScore,
                CuringGroup = t.CuringGroup,
                CrnId = t.CrnId,
                LocInputType = t.LocInputType
            })
            .ToList();
        return result;
    }
    //TODO  修改次方法查询值优化 2025-03-26
    public List<PORcsLocation> GetAllInNoTaskLocationsV3()
    {
        var db = Db.Default;
        var result = db.RcsLocations.FromSqlRaw(@"SELECT * 
                    FROM [rcs_location] [r] with(nolock)
                    WHERE [r].[loc_type] = 33 AND [r].[use_flag] = 1 
                    AND [r].[loc_enable] = 1 AND [r].[err_in_has] = 0 AND [r].[err_out_empty] = 0 AND [r].[loc_has_sku] = 0
                    AND [r].[task_occupy]=0").ToList();


        return result;
    }

    public List<PORcsLocation> GetAllInNoTaskLocationsV2()
    {
        var db = Db.Default;
        //TODO  修改 指定返回的数据 而不是返回所有 2025-03-27
        #region MyRegion
        //var result = db.RcsLocations.FromSqlRaw(@"SELECT 
        //              objid
        //             ,loc_code
        //             ,loc_name
        //             ,plc_code
        //             ,sku_max_count
        //             ,sku_min_count
        //             ,sku_real_count
        //             ,loc_type
        //             ,group_id
        //             ,group_index
        //             ,axis_x
        //             ,axis_y
        //             ,axis_z
        //             ,axis_t
        //             ,n_axis_x
        //             ,n_axis_z
        //             ,n_axis_y
        //             ,n_axis_t
        //             ,area_index
        //             ,row_index
        //             ,col_index
        //             ,loc_has_sku
        //             ,loc_has_sku_time
        //             ,loc_height
        //             ,task_id
        //             ,task_occupy
        //             ,task_occupy_time
        //             ,loc_enable
        //             ,in_enable
        //             ,out_enable
        //             ,material_id
        //             ,product_code
        //             ,product_batch
        //             ,md_time
        //             ,err_out_empty
        //             ,err_in_has
        //             ,err_code
        //             ,err_msg
        //             ,user_id
        //             ,user_name
        //             ,use_flag
        //             ,loc_tire_type
        //             ,loc_max_outsize
        //             ,loc_min_outsize
        //             ,relate_score
        //             ,curing_group
        //             ,crn_id
        //             ,create_time
        //             ,loc_input_type 
        //            FROM [rcs_location] [r] with(nolock)
        //            WHERE [r].[loc_type] = 33 AND [r].[use_flag] = 1 
        //            AND [r].[loc_enable] = 1 AND [r].[err_in_has] = 0 AND [r].[err_out_empty] = 0 AND [r].[loc_has_sku] = 0
        //            AND [r].[task_occupy]=0").ToList(); 
        #endregion

        var result = db.RcsLocations.Where(d=>d.LocType== 33 && d.UseFlag==1 && d.LocEnable==1 && d.ErrInHas==0 && d.ErrOutEmpty==0 && d.LocHasSku==0
        &&d.TaskOccupy==0).Select(t => new PORcsLocation()
        {
            Id = t.Id,
            LocCode = t.LocCode,
            LocName = t.LocName,
            PlcCode = t.PlcCode,
            LocType = t.LocType,
            GroupId = t.GroupId,
            GroupIndex = t.GroupIndex,
            AxisX = t.AxisX,
            AxisY = t.AxisY,
            AxisZ = t.AxisZ,
            AxisT = t.AxisT,
            NAxisX = t.NAxisX,
            NAxisY = t.NAxisY,
            NAxisZ = t.NAxisZ,
            NAxisT = t.NAxisT,
            LocHasSku = t.LocHasSku,
            LocHasSkuTime = t.LocHasSkuTime,
            TaskId = t.TaskId,
            TaskOccupy = t.TaskOccupy,
            TaskOccupyTime = t.TaskOccupyTime,
            LocEnable = t.LocEnable,
            InEnable = t.InEnable,
            OutEnable = t.OutEnable,
            MaterialId = t.MaterialId,
            ProductCode = t.ProductCode,
            MdTime = t.MdTime,
            ErrOutEmpty = t.ErrOutEmpty,
            ErrInHas = t.ErrInHas,
            UpdateTime = t.UpdateTime,
            UseFlag = t.UseFlag,
            LocHeight = t.LocHeight,
            LocMinOutsize = t.LocMinOutsize,
            LocMaxOutsize = t.LocMaxOutsize,
            LocTireType = t.LocTireType,
            RelateScore = t.RelateScore,
            CuringGroup = t.CuringGroup,
            CrnId = t.CrnId,
            LocInputType = t.LocInputType
        }) .ToList();
        return result;

        //var result = GetAllNoHasLocationsISLoc()
        //    .Where(t => t.InEnable == 1 && t.TaskOccupy == 0)
        //    .ToList();
        //return result;



        //List<PORcsLocation> result = new List<PORcsLocation>();
        //var dbHelper = new DbHelper();
        //var sql = new StringBuilder();

        //sql.Append(@$"SELECT [r].[objid] as Id ,
        //            [r].[err_in_has] as ErrInHas, 
        //            [r].[err_out_empty] as ErrOutEmpty, 
        //            [r].[group_id] as GroupId, 
        //            [r].[group_index] as GroupIndex ,
        //            [r].[in_enable] as InEnable, 
        //            [r].[loc_code] as LocCode,
        //            [r].[loc_enable] as LocEnable, 
        //            [r].[loc_has_sku] as LocHasSku, 
        //            [r].[loc_has_sku_time] as LocHasSkuTime, 
        //            [r].[loc_height] as LocHeight,
        //            [r].[loc_max_outsize] as LocMaxOutsize,
        //            [r].[loc_min_outsize] as LocMinOutsize,
        //            [r].[loc_name] as LocName , 
        //            [r].[loc_tire_type] as LocTireType, 
        //            [r].[loc_type] as LocType, 
        //            [r].[material_id] as MaterialId,
        //            [r].[md_time] as MdTime,
        //            [r].[out_enable] as OutEnable ,
        //            [r].[plc_code] as PlcCode,
        //            [r].[task_id] as TaskId,
        //            [r].[task_occupy] as TaskOccupy, 
        //            [r].[task_occupy_time] as TaskOccupyTime, 
        //            [r].[update_time] as UpdateTime, 
        //            [r].[use_flag] as UseFlag
        //            FROM [rcs_location] AS [r] with(nolock)
        //            WHERE [r].[loc_type] = 33 AND [r].[use_flag] = 1 
        //            AND [r].[loc_enable] = 1 AND [r].[err_in_has] = 0 AND [r].[err_out_empty] = 0 AND [r].[loc_has_sku] = 0
        //            AND [r].[task_occupy]=0");


        //dbHelper.CommandText = sql.ToString();
        //dbHelper.CommandType = System.Data.CommandType.Text;
        //var data = dbHelper.GetXDataTable();
        //if (data is not null && data.Rows.Length > 0)
        //{
        //    for (int i = 0; i < data.Rows.Length; i++)
        //    {
        //        PORcsLocation location = new PORcsLocation();
        //        var row = data.DataTable.Rows[i];
        //        location.Id = !string.IsNullOrWhiteSpace(row.Value(nameof(location.Id))) ? Convert.ToInt64(row.Value(nameof(location.Id))) : 0;
        //        location.ErrInHas = !string.IsNullOrWhiteSpace(row.Value(nameof(location.ErrInHas))) ? Convert.ToInt32(row.Value(nameof(location.ErrInHas))) : 0;
        //        location.ErrOutEmpty = !string.IsNullOrWhiteSpace(row.Value(nameof(location.ErrOutEmpty))) ? Convert.ToInt32(row.Value(nameof(location.ErrOutEmpty))) : 0;
        //        location.GroupId = !string.IsNullOrWhiteSpace(row.Value(nameof(location.GroupId))) ? Convert.ToInt64(row.Value(nameof(location.GroupId))) : 0;
        //        location.GroupIndex = !string.IsNullOrWhiteSpace(row.Value(nameof(location.GroupIndex))) ? Convert.ToInt32(row.Value(nameof(location.GroupIndex))) : 0;
        //        location.InEnable = !string.IsNullOrWhiteSpace(row.Value(nameof(location.InEnable))) ? Convert.ToInt32(row.Value(nameof(location.InEnable))) : 0;
        //        location.LocCode = row.Value(nameof(location.LocCode));
        //        location.LocEnable = !string.IsNullOrWhiteSpace(row.Value(nameof(location.LocEnable))) ? Convert.ToInt32(row.Value(nameof(location.LocEnable))) : 0;
        //        location.LocHasSku = !string.IsNullOrWhiteSpace(row.Value(nameof(location.LocHasSku))) ? Convert.ToInt32(row.Value(nameof(location.LocHasSku))) : 0;
        //        location.LocHasSkuTime = !string.IsNullOrWhiteSpace(row.Value(nameof(location.LocHasSkuTime))) ? Convert.ToDateTime(row.Value(nameof(location.LocHasSkuTime))) : null;
        //        location.LocHeight = !string.IsNullOrWhiteSpace(row.Value(nameof(location.LocHeight))) ? Convert.ToDecimal(row.Value(nameof(location.LocHeight))) : 0;
        //        location.LocMaxOutsize = !string.IsNullOrWhiteSpace(row.Value(nameof(location.LocMaxOutsize))) ? Convert.ToDecimal(row.Value(nameof(location.LocMaxOutsize))) : 0;
        //        location.LocMinOutsize = !string.IsNullOrWhiteSpace(row.Value(nameof(location.LocMinOutsize))) ? Convert.ToDecimal(row.Value(nameof(location.LocMinOutsize))) : 0;
        //        location.LocName = row.Value(nameof(location.LocName));
        //        location.LocTireType = !string.IsNullOrWhiteSpace(row.Value(nameof(location.LocTireType))) ? Convert.ToInt32(row.Value(nameof(location.LocTireType))) : 0;
        //        location.LocType = !string.IsNullOrWhiteSpace(row.Value(nameof(location.LocType))) ? Convert.ToInt32(row.Value(nameof(location.LocType))) : 0;
        //        location.MaterialId = !string.IsNullOrWhiteSpace(row.Value(nameof(location.MaterialId))) ? Convert.ToInt64(row.Value(nameof(location.MaterialId))) : 0;
        //        location.MdTime = !string.IsNullOrWhiteSpace(row.Value(nameof(location.MdTime))) ? Convert.ToDateTime(row.Value(nameof(location.MdTime))) : null;
        //        location.OutEnable = !string.IsNullOrWhiteSpace(row.Value(nameof(location.OutEnable))) ? Convert.ToInt32(row.Value(nameof(location.OutEnable))) : 0;
        //        location.PlcCode = row.Value(nameof(location.PlcCode));
        //        location.TaskId = !string.IsNullOrWhiteSpace(row.Value(nameof(location.TaskId))) ? Convert.ToInt64(row.Value(nameof(location.TaskId))) : 0;
        //        location.TaskOccupy = !string.IsNullOrWhiteSpace(row.Value(nameof(location.TaskOccupy))) ? Convert.ToInt32(row.Value(nameof(location.TaskOccupy))) : 0;
        //        location.TaskOccupyTime = !string.IsNullOrWhiteSpace(row.Value(nameof(location.TaskOccupyTime))) ? Convert.ToDateTime(row.Value(nameof(location.TaskOccupyTime))) : null;
        //        location.UpdateTime = !string.IsNullOrWhiteSpace(row.Value(nameof(location.UpdateTime))) ? Convert.ToDateTime(row.Value(nameof(location.UpdateTime))) : null;
        //        location.UseFlag = !string.IsNullOrWhiteSpace(row.Value(nameof(location.UseFlag))) ? Convert.ToInt32(row.Value(nameof(location.UseFlag))) : 0;
        //        result.Add(location);
        //    }
        //}
        //return result;
    }

    public List<PORcsLocation> GetAllOutNoTaskLocations()
    {
        var db = Db.Default;
        var result = db.RcsLocations
            .Where(t => t.UseFlag == 1 && t.LocEnable == 1
            && t.ErrInHas == 0
            && t.ErrOutEmpty == 0
            && t.OutEnable == 1
            && t.TaskOccupy == 0)
           .Select(t => new PORcsLocation()
           {
               Id = t.Id,
               LocCode = t.LocCode,
               LocName = t.LocName,
               PlcCode = t.PlcCode,
               LocType = t.LocType,
               GroupId = t.GroupId,
               GroupIndex = t.GroupIndex,
               AxisX = t.AxisX,
               AxisY = t.AxisY,
               AxisZ = t.AxisZ,
               AxisT = t.AxisT,
               NAxisX = t.NAxisX,
               NAxisY = t.NAxisY,
               NAxisZ = t.NAxisZ,
               NAxisT = t.NAxisT,
               LocHasSku = t.LocHasSku,
               LocHasSkuTime = t.LocHasSkuTime,
               TaskId = t.TaskId,
               TaskOccupy = t.TaskOccupy,
               TaskOccupyTime = t.TaskOccupyTime,
               LocEnable = t.LocEnable,
               InEnable = t.InEnable,
               OutEnable = t.OutEnable,
               MaterialId = t.MaterialId,
               ProductCode = t.ProductCode,
               MdTime = t.MdTime,
               ErrOutEmpty = t.ErrOutEmpty,
               ErrInHas = t.ErrInHas,
               UseFlag = t.UseFlag,
               LocHeight = t.LocHeight,
               LocMinOutsize = t.LocMinOutsize,
               LocMaxOutsize = t.LocMaxOutsize,
               LocTireType = t.LocTireType,
               RelateScore = t.RelateScore,
               CuringGroup = t.CuringGroup,
               CrnId = t.CrnId,
               LocInputType = t.LocInputType
           })
            .ToList();
        return result;
    }
    public List<OutLocationNoTaskBean> GetAllOutNoTaskLocationsV3(int locType)
    {
        var db = Db.Default;
        var result = db.RcsLocations
            .Where(t => t.UseFlag == 1 && t.LocEnable == 1
            && t.ErrInHas == 0
            && t.ErrOutEmpty == 0
            && t.OutEnable == 1
            && t.TaskOccupy == 0
            && t.LocType == locType
            ).Select(t => new OutLocationNoTaskBean
            {
                GroupId = t.GroupId,
                GroupIndex = t.GroupIndex,
                Id = t.Id,
                MaterialId = t.MaterialId,
                MdTime = t.MdTime,
            })
            .ToList();
        return result;
    }
    public List<PORcsLocation> GetAllOutNoTaskLocationsV2()
    {
        //var db = Db.Default;
        var result = GetAllLocationsISLoc()
            .Where(t => t.OutEnable == 1 && t.TaskOccupy == 0)
            .ToList();
        return result;
    }


    public List<long> GetGoodLocs()
    {
        var db = Db.Default;
        var result = db.RcsLocations
            .Where(t => t.UseFlag == 1 && t.LocEnable == 1
            && t.ErrInHas == 0
            && t.ErrOutEmpty == 0 && t.OutEnable == 1 && t.TaskOccupy == 0 && t.LocHasSku == 1).Select(t => t.Id.GetValueOrDefault()).ToList();
        return result;
    }

    public List<PORcsLocation> GetInStockLocations(EnumInStockType enumInStockType) => enumInStockType switch
    {
        EnumInStockType.Warehousing => GetAllInNoTaskLocations().Where(t => t.LocHasSku == 0).ToList(),
        EnumInStockType.ExWarehouse => GetAllOutNoTaskLocations().Where(t => t.LocHasSku == 1).ToList(),
        _ => new List<PORcsLocation>(),
    };

    // public List<PORcsLocation> GetNoGoodsLocations() => GetAllInNoTaskLocations().Where(t => t.LocHasSku == 0).ToList();
    public List<PORcsLocation> GetNoGoodsLocations() => GetAllInNoTaskLocationsV2();
    public LocationHasBean GetHasSkuLocations()
    {
        var locations = GetAllInNoTaskLocations();
        return new LocationHasBean
        {
            NoGoods = locations.Where(t => t.LocHasSku == 0 && t.LocType == (int)EnumLocType.Location).ToList(),
            InStock = locations.Where(t => t.LocHasSku == 1 && t.LocType == (int)EnumLocType.Location).ToList()
        };
    }

    public PORcsLocation GetLocationById(long id)
    {
        var db = Db.Default;
        var result = db.RcsLocations
            .Where(t => t.UseFlag == 1 && t.Id == id)
            .FirstOrDefault();
        return result;
    }
    public List<PORcsLocation> GetLocationByCrnId(long crnId)
    {

        var db = Db.Default;
        var result = db.RcsLocations
            .Where(t => t.UseFlag == 1 && t.CrnId == crnId && t.InEnable == 1)
            .Select(t => new PORcsLocation()
            {
                Id = t.Id,
                LocCode = t.LocCode,
                LocName = t.LocName,
                PlcCode = t.PlcCode,
                LocType = t.LocType,
                GroupId = t.GroupId,
                GroupIndex = t.GroupIndex,
                AxisX = t.AxisX,
                AxisY = t.AxisY,
                AxisZ = t.AxisZ,
                AxisT = t.AxisT,
                NAxisX = t.NAxisX,
                NAxisY = t.NAxisY,
                NAxisZ = t.NAxisZ,
                NAxisT = t.NAxisT,
                LocHasSku = t.LocHasSku,
                LocHasSkuTime = t.LocHasSkuTime,
                TaskId = t.TaskId,
                TaskOccupy = t.TaskOccupy,
                TaskOccupyTime = t.TaskOccupyTime,
                LocEnable = t.LocEnable,
                InEnable = t.InEnable,
                OutEnable = t.OutEnable,
                MaterialId = t.MaterialId,
                ProductCode = t.ProductCode,
                MdTime = t.MdTime,
                ErrOutEmpty = t.ErrOutEmpty,
                ErrInHas = t.ErrInHas,
                UpdateTime = t.UpdateTime,
                UseFlag = t.UseFlag,
                LocHeight = t.LocHeight,
                LocMinOutsize = t.LocMinOutsize,
                LocMaxOutsize = t.LocMaxOutsize,
                LocTireType = t.LocTireType,
                RelateScore = t.RelateScore,
                CuringGroup = t.CuringGroup,
                CrnId = t.CrnId,
                LocInputType = t.LocInputType
            })
            .ToList();
        return result;
    }
    public List<PORcsLocation> GetLoctionByLocCode(string locCode)
    {
        var db = Db.Default;
        var result = db.RcsLocations
            .Where(t => t.UseFlag == 1 && t.LocCode == locCode)
           .Select(t => new PORcsLocation()
           {
               Id = t.Id,
               LocCode = t.LocCode,
               LocName = t.LocName,
               PlcCode = t.PlcCode,
               LocType = t.LocType,
               GroupId = t.GroupId,
               GroupIndex = t.GroupIndex,
               AxisX = t.AxisX,
               AxisY = t.AxisY,
               AxisZ = t.AxisZ,
               AxisT = t.AxisT,
               NAxisX = t.NAxisX,
               NAxisY = t.NAxisY,
               NAxisZ = t.NAxisZ,
               NAxisT = t.NAxisT,
               LocHasSku = t.LocHasSku,
               LocHasSkuTime = t.LocHasSkuTime,
               TaskId = t.TaskId,
               TaskOccupy = t.TaskOccupy,
               TaskOccupyTime = t.TaskOccupyTime,
               LocEnable = t.LocEnable,
               InEnable = t.InEnable,
               OutEnable = t.OutEnable,
               MaterialId = t.MaterialId,
               ProductCode = t.ProductCode,
               MdTime = t.MdTime,
               ErrOutEmpty = t.ErrOutEmpty,
               ErrInHas = t.ErrInHas,
               UpdateTime = t.UpdateTime,
               UseFlag = t.UseFlag,
               LocHeight = t.LocHeight,
               LocMinOutsize = t.LocMinOutsize,
               LocMaxOutsize = t.LocMaxOutsize,
               LocTireType = t.LocTireType,
               RelateScore = t.RelateScore,
               CuringGroup = t.CuringGroup,
               CrnId = t.CrnId,
               LocInputType = t.LocInputType
           })
            .ToList();
        return result;
    }

    public PORcsLocation GetNextCuringLoc(long locId)
    {
        var db = Db.Default;


        var loc = db.RcsLocations.Where(t => t.Id == locId).FirstOrDefault();
        var group = loc.CuringGroup ?? 0;
        var relateScore = loc.RelateScore ?? 0;

        var result = db.RcsLocations.Where(t => t.CuringGroup == group && t.RelateScore > relateScore).OrderBy(t => t.RelateScore).FirstOrDefault();
        return result;
    }

    public bool HasLocationById(long id) => GetLocationById(id) != null;

    public int UpdateLocationHasTask(long locId, long taskId, long skuId)
    {
        var db = Db.Default;
        var prodSku = _ProdSku.GetProdSkuById(skuId);
        if (prodSku == null)
        {
            WriteLog($"-3：{skuId},为找到SKU信息.");
            return 0;
        }
        DateTime dateTime = DateTime.Now;
        var result = db.RcsLocations
            .Where(t => t.UseFlag == 1 && t.Id == locId)
            .Update(new PORcsLocation
            {
                TaskId = taskId,
                TaskOccupy = 1,
                TaskOccupyTime = dateTime,

                LocHasSku = 1,
                LocHasSkuTime = dateTime,
                MaterialId = prodSku.MaterialId,

            });
        db.SaveChanges();

        return result;
    }
    public int ClearLocationHasTask(long locId)
    {
        var db = Db.Default;

        var dateTime = System.DateTime.Now;
        var result = db.RcsLocations
            .Where(t => t.UseFlag == 1 && t.Id == locId)
            .Update(new PORcsLocation
            {
                TaskId = null,
                TaskOccupy = 0,
                LocHasSku = 0,
                UpdateTime = dateTime,
                LocHasSkuTime = null,
                MaterialId = null,
                TaskOccupyTime = null,
                MdTime = null
            });
        db.SaveChanges();
        return result;
    }
    public int UpdateLocationHasSku(long? materialId,
        DateTime? mdTime,
        long? startLocId = 0,
        long? targetLocId = 0)
    {
        var startnum = 1;
        var targetnum = 1;
        if (startLocId != 0)
        {
            startnum = UpdateLocationNoGood(startLocId);
        }

        if (targetLocId != 0)
        {
            targetnum = UpdateLocationHasGood(materialId, targetLocId, mdTime);
        }

        return startnum & targetnum;
    }

    public int UpdateLocationHasGood(long? materialId, long? locId, DateTime? mdTime)
    {
        var db = Db.Default;
        var dateTime = DateTime.Now;
        var result = 0;

        result = db.RcsLocations.Where(t => t.UseFlag == 1 && t.Id == locId).Update(new PORcsLocation
        {
            TaskId = null,
            TaskOccupy = 0,
            LocHasSku = 1,
            LocHasSkuTime = dateTime,
            MaterialId = materialId,
            UpdateTime = dateTime,
            MdTime = mdTime
        });
        return db.SaveChanges();
    }

    public int UpdateLocationNoGood(long? locId)
    {
        var db = Db.Default;
        var dateTime = DateTime.Now;
        var result = 0;
        result = db.RcsLocations.Where(t => t.UseFlag == 1 && t.Id == locId).Update(new PORcsLocation
        {
            TaskId = null,
            TaskOccupy = 0,
            LocHasSku = 0,
            UpdateTime = dateTime,
            LocHasSkuTime = null,
            MaterialId = null,
            TaskOccupyTime = null,
            MdTime = null,
            ProductCode = null,
        });

        int i = db.SaveChanges();

        WriteLog($"更新UpdateLocationNoGood 返回值：{i};result返回值{result}",true);
        return i;
    }
    //task.SkuId, 0, task.CurrentLoc, true
    public int UpdateLocationAndWcsLocWithSkuId(
        long? skuId,
        long? startLocId = 0,
        long? targetLocId = 0,
        bool isDelTarget = false)
    {
        var prodSku = _ProdSku.GetProdSkuById(skuId);
        if (prodSku == null)
        {
            return 0;
        }
        var materialId = prodSku?.MaterialId ?? 0;
        var mdTime = prodSku?.MdTime;



        var location = UpdateLocationHasSku(materialId, mdTime, startLocId, targetLocId);
        var wcsLoc = _WcsLocSku.SetWcsLocSku(targetLocId, skuId, isDelTarget);



        return location & wcsLoc;
    }

    public int UpdateLocationAndWcsLocWithTaskId(
        long? taskId,
        long? startLocId = 0,
        long? targetLocId = 0)
    {
        var task = _Task.GetTaskByTaskId(taskId.GetValueOrDefault());
        if (task?.SkuId is not long skuId)
        {
            return 0;
        }
        var prodSku = _ProdSku.GetProdSkuById(skuId);
        if (prodSku?.MaterialId is not long materialId)
        {
            return 0;
        }
        var mdTime = prodSku.MdTime;
        var location = UpdateLocationHasSku(materialId, mdTime, startLocId, targetLocId);
        var wcsLoc = _WcsLocSku.SetWcsLocSku(skuId, targetLocId);

        return location & wcsLoc;
    }

    public List<LocationInfo> GetNoGoodsLocation(List<CrnForkInfo> crnForkInfos)
    {
        var taskNogood = GetNoGoodsLocations();
        var usableCrnForkInfos = crnForkInfos.Where(t => t.IsEnable == true).ToList(); // 可用
        var abnormalCrnForkInfos = crnForkInfos.Where(t => t.IsEnable == false).ToList(); // 异常
        // 堆垛机管理空货位
        var equipLocHold = _WcsEquipLocHold.GetNoGoodsEquipLocHoldsByCrn(usableCrnForkInfos, abnormalCrnForkInfos, taskNogood, false);

        // 堆垛机对应实际货位
        var locations = GetAllInNoTaskLocations();

        var result = equipLocHold
            .Join(locations,
            f => f.LocId,
            s => s.Id,
            (f, s) => new LocationInfo
            {
                Id = s.Id,
                MaterialId = s.MaterialId,
                AreaId = f.AreaId,
                CrnId = f.EquipId,
                GroupId = s.GroupId,
                GroupIndex = s.GroupIndex,
                RelateScore = f.RelateScore,
                LocHeight = s.LocHeight,
                LocTireType = s.LocTireType,
                LocMaxOutsize = s.LocMaxOutsize,
                LocMinOutsize = s.LocMinOutsize,
                LocInputType=s.LocInputType
            }).OrderBy(t => t.RelateScore)
            .ThenBy(t => t.GroupId)
            .ThenBy(t => t.GroupIndex)
            .ToList();
        return result;
    }



    //public List<LocationInfo> GetNoGoodsLocationByHeight(List<CrnForkInfo> crnForkInfos, decimal height, decimal outSide)
    //{
    //    var taskNogood = GetNoGoodsLocations();
    //    var usableCrnForkInfos = crnForkInfos.Where(t => t.IsEnable == true).ToList(); // 可用
    //    var abnormalCrnForkInfos = crnForkInfos.Where(t => t.IsEnable == false).ToList(); // 异常
    //    // 堆垛机管理空货位
    //    var equipLocHold = _WcsEquipLocHold.GetNoGoodsEquipLocHoldsByCrnAndHeight(usableCrnForkInfos, abnormalCrnForkInfos, taskNogood, height, outSide, false);

    //    // 堆垛机对应实际货位
    //    var locations = GetAllInNoTaskLocations();

    //    var result = equipLocHold
    //        .Join(locations,
    //        f => f.LocId,
    //        s => s.Id,
    //        (f, s) => new LocationInfo
    //        {
    //            Id = s.Id,
    //            MaterialId = s.MaterialId,
    //            AreaId = f.AreaId,
    //            CrnId = f.EquipId,
    //            GroupId = s.GroupId,
    //            GroupIndex = s.GroupIndex,
    //            RelateScore = f.RelateScore,
    //            LocHeight = s.LocHeight,
    //            LocTireType = s.LocTireType,
    //        }).OrderBy(t => t.RelateScore)
    //        .ThenBy(t => t.GroupId)
    //        .ThenBy(t => t.GroupIndex)
    //        .ToList();
    //    return result;
    //}

    private List<LocationInfo> GetGoodsLocation(List<CrnForkInfo> crnForkInfos)
    {
        // 堆垛机管理有货货位    (已经去掉停机货位) (不显示 产品质量为 N 产品)
        var equipLocHold = _WcsEquipLocHold.GetGoodsEquipLocHolds(crnForkInfos);

        var locations = GetAllOutNoTaskLocations();

        //OLDTODO 【已解决】有货时间用了 md_time 生产时间 ( 入库完成时修改 md_time)
        var result = equipLocHold
                .Join(locations,
                f => f.LocId,
                s => s.Id,
                (f, s) => new LocationInfo
                {
                    Id = s.Id,
                    MaterialId = s.MaterialId,
                    MdTime = s.MdTime,
                    AreaId = f.AreaId,
                    CrnId = f.EquipId,
                    GroupId = s.GroupId,
                    GroupIndex = s.GroupIndex,
                    RelateScore = f.RelateScore,
                }).OrderBy(t => t.RelateScore)
                .ThenBy(t => t.GroupId)
                .ThenBy(t => t.GroupIndex)
                .ToList();
        return result;
    }
    private List<LocationInfo> GetGoodsLocationV2(List<CrnForkInfo> crnForkInfos, List<ProductLocBean> productN, List<POWcsEquipLocHold> wcsEquipLocHolds)
    {

        var equipLocHoldResult = Task.Run(() =>
        {
            // 堆垛机管理有货货位    (已经去掉停机货位) (不显示 产品质量为 N 产品)
            var equipLocHold = _WcsEquipLocHold.GetGoodsEquipLocHoldsV2(crnForkInfos, productN, wcsEquipLocHolds);
            return equipLocHold;
        });
        var loccationsResult = Task.Run(() =>
        {
            //var locations = GetAllOutNoTaskLocations();
            var locations = GetAllOutNoTaskLocationsV3((int)EnumLocType.Location);
            return locations;
        });

        //WriteLog($"GetGoodsLocationV2-111", true);
        var equipLocHold = equipLocHoldResult.Result;

        //WriteLog($"GetGoodsLocationV2-222", true);
        var locations = loccationsResult.Result;

        // WriteLog($"GetGoodsLocationV2-333", true);
        //var materials = _ProdMaterial.GetMaterials();

        _ = double.TryParse(_WmsSetting.GetWmsSettingByCode(ConstFields.ExWarehousingTimeOut).Value, out var outTime);
        //OLDTODO 【已解决】有货时间用了 md_time 生产时间 ( 入库完成时修改 md_time)
        var result = equipLocHold
                .Join(locations,
                f => f.LocId,
                s => s.Id,
                (f, s) => new LocationInfo
                {
                    Id = s.Id,
                    MaterialId = s.MaterialId,
                    MdTime = s.MdTime,
                    AreaId = f.AreaId,
                    CrnId = f.EquipId,
                    GroupId = s.GroupId,
                    GroupIndex = s.GroupIndex,
                    RelateScore = f.RelateScore,
                    IsTimeOut = 0,// DateTime.Now<s. 1 : 0
                    //s.MdTime,
                    //IsTimeOut = (DateTime.Now.Subtract(s.MdTime ?? DateTime.Now).TotalMinutes - outTime) >= 0 ? 1 : 0,
                })

                //.Join(materials, f => f.MaterialId, s => s.Id, (f, s) => new LocationInfo
                //{

                //    Id = f.Id,
                //    MaterialId = f.MaterialId,
                //    MdTime = f.MdTime,
                //    AreaId = f.AreaId,
                //    CrnId = f.CrnId,
                //    GroupId = f.GroupId,
                //    GroupIndex = f.GroupIndex,
                //    RelateScore = f.RelateScore,
                //    IsTimeOut = (DateTime.Now.Subtract(f.MdTime ?? DateTime.Now).TotalMinutes - outTime) >= 0 ? 1 : 0,
                //})
                .OrderBy(t=>t.MdTime)
                .ThenBy(t => t.RelateScore)
                .ThenBy(t => t.GroupId)
                .ThenBy(t => t.GroupIndex)
                .ToList();
        //WriteLog($"GetGoodsLocationV2-444", true);
        return result;
    }

    //class LocationAreaInfo
    //{
    //    public long? CrnId { get; set; }
    //    public long? AreaId { get; set; }
    //    public List<LocationInfo> LocationInfos { get; set; }
    //}

    [Obsolete("禁用", true)]
    public List<LocationGroupInfo> GetGoodsLocationByCrnIdGroup(List<CrnForkInfo> crnForkInfos, int minute)
    {
        //获取堆垛机负责的有货位
        var locationInfos = GetGoodsLocation(crnForkInfos);

        // 堆垛机汇总
        LocationDoubleGroup(locationInfos, crnForkInfos);


        var result = locationInfos.GroupBy(t => new { t.CrnId, t.MaterialId })
            .Select(t => new LocationGroupInfo
            {
                CrnId = t.Key.CrnId,
                MaterialId = t.Key.MaterialId,
                //OLDTODO 【重点测试】时间小于 第二最小时间 + minute
                LocationInfos = t.Where(f => f.MdTime.Value <= t.OrderBy(t => t.MdTime).TakeLast(2).FirstOrDefault().MdTime.Value.AddMinutes(minute)).ToList()
            }).ToList();
        return result;
    }
    //原先逻辑备份 lsq
    [Obsolete("禁用", true)]
    public List<LocationGroupInfo> GetGoodsLocationByAreaIdGroupBak(List<CrnForkInfo> crnForkInfos, int minute)
    {
        //获取堆垛机负责的有货位
        var locationInfos = GetGoodsLocation(crnForkInfos);

        // 堆垛机汇总
        LocationDoubleGroup(locationInfos, crnForkInfos);

        // 区域给定时间内的货位
        var areaLocations = locationInfos.GroupBy(t => new { t.AreaId, t.MaterialId })
            .Select(t => new
            {
                AreaId = t.Key.AreaId,
                MaterialId = t.Key.MaterialId,
                //OLDTODO【重点测试】时间小于 第二最小时间 + minute
                //OLDTODO 李声强 再验证 TakeLast
                LocationInfos = t.Where(f => f.MdTime.Value <= t.OrderBy(t => t.MdTime).TakeLast(2).FirstOrDefault().MdTime.Value.AddMinutes(minute)).ToList()
            }).SelectMany(t => t.LocationInfos).ToList();

        // 堆垛机货位汇总
        var result = areaLocations.GroupBy(t => new { t.CrnId, t.MaterialId })
            .Select(t => new LocationGroupInfo
            {
                CrnId = t.Key.CrnId,
                MaterialId = t.Key.MaterialId,
                //OLDTODO【重点测试】时间小于 第二最小时间 + minute
                LocationInfos = t.ToList()
            }).ToList();
        return result;
    }
    //新调整逻辑 原有逻辑在上面 lsq
    public List<LocationGroupInfo> GetGoodsLocationByAreaIdGroup(List<CrnForkInfo> crnForkInfos)
    {
        //获取堆垛机负责的有货位
        var locationInfos = GetGoodsLocation(crnForkInfos);

        // 堆垛机汇总（判断有货货位是否配对）
        LocationDoubleGroup(locationInfos, crnForkInfos);
        var crnIds = crnForkInfos.Where(t => t.IsEnable == false).Select(t => t.CrnId).Distinct().ToList();

        // 堆垛机货位汇总        
        var result = locationInfos.Where(t => !crnIds.Contains(t.CrnId)).GroupBy(t => new { t.CrnId, t.MaterialId })
            .Select(x => new LocationGroupInfo
            {
                CrnId = x.Key.CrnId,
                MaterialId = x.Key.MaterialId,
                MinTime = x.OrderBy(t => t.MdTime).Select(t => t.MdTime).FirstOrDefault(),
                LocationInfos = x.ToList()
            }).ToList();
        return result;
    }


    //新调整逻辑 原有逻辑在上面 lsq
    public List<LocationGroupInfo> GetGoodsLocationByAreaIdGroupV2(List<CrnForkInfo> crnForkInfos, List<ProductLocBean> productN, List<POWcsEquipLocHold> wcsEquipLocHolds)
    {
        // 获取堆垛机负责的有货位
        //WriteLog($"GetGoodsLocationByAreaIdGroupV2-111", true);
        var locationInfos = GetGoodsLocationV2(crnForkInfos, productN, wcsEquipLocHolds);
        // WriteLog($"GetGoodsLocationByAreaIdGroupV2-222", true);

        // 堆垛机汇总（判断有货货位是否配对）
        LocationDoubleGroup(locationInfos, crnForkInfos);
        //var locations = LocationDoubleGroupv2(locationInfos, crnForkInfos);
        //WriteLog($"GetGoodsLocationByAreaIdGroupV2-333", true);
        var crnIds = crnForkInfos.Where(t => t.IsEnable == false).Select(t => t.CrnId).Distinct().ToList();

        // 堆垛机货位汇总        
        var result = locationInfos.Where(t => !crnIds.Contains(t.CrnId)).GroupBy(t => new { t.CrnId, t.MaterialId })
            .Select(x => new LocationGroupInfo
            {
                CrnId = x.Key.CrnId,
                MaterialId = x.Key.MaterialId,
                MinTime = x.OrderBy(t => t.MdTime).Select(t => t.MdTime).FirstOrDefault(),
                IsTimeOut = x.Count(t => t.IsTimeOut == 1) > 0 ? 1 : 0,
                LocationInfos = x.ToList()
            }).ToList();
        //WriteLog($"GetGoodsLocationByAreaIdGroupV2-444", true);
        return result;
    }

    [Obsolete("禁用", true)]
    public List<LocationGroupInfo> GetGoodsLocationByLibrarydGroup(List<CrnForkInfo> crnForkInfos, int minute)
    {
        //获取堆垛机负责的有货位
        var locationInfos = GetGoodsLocation(crnForkInfos);

        // 堆垛机汇总
        LocationDoubleGroup(locationInfos, crnForkInfos);

        // 所有库存给定时间内的货位
        var areaLocations = locationInfos.GroupBy(t => new { t.MaterialId })
            .Select(t => new
            {
                MaterialId = t.Key.MaterialId,
                //OLDTODO【重点测试】时间小于 第二最小时间 + minute
                LocationInfos = t.Where(f => f.MdTime.Value <= t.OrderBy(t => t.MdTime).TakeLast(2).FirstOrDefault().MdTime.Value.AddMinutes(minute)).ToList()
            }).SelectMany(t => t.LocationInfos).ToList();

        // 堆垛机货位汇总
        var result = areaLocations.GroupBy(t => new { t.CrnId, t.MaterialId })
            .Select(t => new LocationGroupInfo
            {
                CrnId = t.Key.CrnId,
                MaterialId = t.Key.MaterialId,
                //OLDTODO【重点测试】时间小于 第二最小时间 + minute
                LocationInfos = t.ToList()
            }).ToList();
        return result;
    }

    public List<LocationInfo> GetSingleLocation(List<LocationInfo> pORcsLocations)
    {
        var ids = pORcsLocations
             .GroupBy(t => t.GroupId)
             .Select(t => new { GroupId = t.Key, Count = t.Count() })
             .ToList().Where(t => t.Count == 1).Select(t => t.GroupId).ToList();

        var result = pORcsLocations.Where(t => ids.Contains(t.GroupId)).ToList();
        return result;
    }

    /// <summary>
    /// 库位汇总标记是否成对
    /// </summary>
    /// <param name="locationInfos"></param>
    private void LocationDoubleGroup(List<LocationInfo> locationInfos, List<CrnForkInfo> crnForkInfos)
    {
        var group = locationInfos.GroupBy(t => t.GroupId)
            .Select(s => new { GroupId = s.Key.Value, IsDouble = s.Count() == 2 })
            .ToList();
        locationInfos.ForEach(item =>
        {
            item.AreaId = crnForkInfos.Where(t => t.CrnId == item.CrnId).FirstOrDefault()?.CrnArea1;
            item.IsDouble = group.Where(t => t.GroupId == item.GroupId).FirstOrDefault()?.IsDouble ?? false;

        });
    }

    private List<LocationInfo> LocationDoubleGroupv2(List<LocationInfo> locationInfos, List<CrnForkInfo> crnForkInfos)
    {
        var group = locationInfos.GroupBy(t => t.GroupId)
            .Select(s => new { GroupId = s.Key.Value, IsDouble = s.Count() == 2 })
            .ToList();
        var crnForkGroup = crnForkInfos.GroupBy(t => t.CrnId)
            .Select(s => new { CrnId = s.Key.Value, CrnArea1 = s.FirstOrDefault().CrnArea1 })
            .ToList();
        var result = locationInfos.Join(crnForkInfos, f => f.CrnId, s => s.CrnId, (f, s) => new LocationInfo
        {
            AreaId = s.CrnArea1,
            CrnId = f.CrnId,
            Fork = f.Fork,
            GroupId = f.GroupId,
            GroupIndex = f.GroupIndex,
            Id = f.Id,
            IsSingle = f.IsSingle,
            IsTimeOut = f.IsTimeOut,
            LocHeight = f.LocHeight,
            LocMaxOutsize = f.LocMaxOutsize,
            LocMinOutsize = f.LocMinOutsize,
            LocTireType = f.LocTireType,
            MaterialId = f.MaterialId,
            MdTime = f.MdTime,
            RelateScore = f.RelateScore,
            Summary = f.Summary,
            IsDouble = f.IsDouble,
        }).Join(group, f => f.GroupId, s => s.GroupId, (f, s) => new LocationInfo
        {
            AreaId = f.AreaId,
            CrnId = f.CrnId,
            Fork = f.Fork,
            GroupId = f.GroupId,
            GroupIndex = f.GroupIndex,
            Id = f.Id,
            IsSingle = f.IsSingle,
            IsTimeOut = f.IsTimeOut,
            LocHeight = f.LocHeight,
            LocMaxOutsize = f.LocMaxOutsize,
            LocMinOutsize = f.LocMinOutsize,
            LocTireType = f.LocTireType,
            MaterialId = f.MaterialId,
            MdTime = f.MdTime,
            RelateScore = f.RelateScore,
            Summary = f.Summary,
            IsDouble = s.IsDouble,
        }).ToList();

        return result;
    }


    private List<LocationInfo> GetSingleLocationHalf(List<LocationInfo> pORcsLocations, CrnForkInfo fork)
    {
        var db = Db.Default;
        // 货叉管理货位
        var wcsEquipLocHoldLocs = _WcsEquipLocHold.GetEquipLocHolds().Where(t => t.EquipId == fork.CrnId.GetValueOrDefault()).Select(t => t.LocId).ToList();
        // 货叉管理的空货位（所有空货位）
        var pORcsLocationsFork = pORcsLocations.Where(t => wcsEquipLocHoldLocs.Contains(t.Id)).ToList();

        // 有一个空货位 [双：(异常，空)，双：（有货，空），单：（空）]
        var singleEmptys = GetSingleLocation(pORcsLocationsFork);

        // 去掉停机货位
        var halts = _WcsAsrsLocHalt.GetAsrsLocHaltByFork(fork.Fork.GetValueOrDefault()).Select(t => t.LocId).ToList();
        singleEmptys = singleEmptys.Where(t => !halts.Contains(t.Id)).ToList();

        // 获取单一空货位的所在组号
        var groupIds = singleEmptys.Select(t => t.GroupId).ToList();

        // 此堆垛机的所有库位(所有库位跟可用单一空货位关联 如果count=2 证明是双货位 其中一个已被占用)
        var all_locs = GetLocationsByLocIds(wcsEquipLocHoldLocs);
        var rcsGroup = all_locs.Where(t => groupIds.Contains(t.GroupId)).GroupBy(t => t.GroupId)
            .Select(s => new { GroupId = s.Key.Value, Count = s.Count() }).ToList();



        // 双货位[双：（有货，空）]
        var doubleGroup = rcsGroup.Where(t => t.Count == 2).Select(t => t.GroupId).ToList();
        // 单空货位，是配对双库位
        var all_ids = all_locs.Where(t => doubleGroup.Contains(t.GroupId ?? 0)).Select(t => t.Id.GetValueOrDefault()).ToList();
        // 双的无货位 ID 
        var ids = singleEmptys.Where(t => doubleGroup.Contains(t.GroupId ?? 0)).Select(t => t.Id.GetValueOrDefault()).ToList();
        // 双的一个有货位一个无货
        var use_ids = all_ids.Except(ids).ToList();

        // 单所有货位[双：(异常，空)，单：（空）]
        var singleGroup = rcsGroup.Where(t => t.Count == 1).Select(t => t.GroupId).ToList();
        // 需要的 单无货位
        var signle_ids = singleEmptys.Where(t => singleGroup.Contains(t.GroupId ?? 0)).Select(t => t.Id.GetValueOrDefault()).ToList();


        // 所有货位【双有货单胎，单的无货单胎】
        var all_use_ids = use_ids.Concat(signle_ids).ToList();

        // 空货位的另一半（非空）
        var result = db.RcsLocations
            .Where(t => t.UseFlag == 1  && all_use_ids.Contains(t.Id.GetValueOrDefault()))
            .Select(s => new LocationInfo
            {
                Id = s.Id,
                GroupId = s.GroupId,
                GroupIndex = s.GroupIndex,
                MaterialId = s.MaterialId,
                LocInputType=s.LocInputType,//新增 是否配对货位 1是 2否  202507-24
                IsSingle = signle_ids.Contains(s.Id.GetValueOrDefault()), // 【False：（双：(异常，空)，单：（空））；True：双：（有货，空）】
            })
            .OrderBy(t => t.GroupId).ToList();

        return result;
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="pORcsLocations">堆垛机持有的可用空货位</param>
    /// <param name="materialId">物料id</param>
    /// <param name="fork">堆垛机货叉</param>
    /// <param name="groupId">组号</param>
    /// <returns></returns>
    public LocationInfo GetTagertSingleLoc(List<LocationInfo> pORcsLocations,long? materialId,CrnForkInfo fork, int? taskGroup)
    {
        // singleHalf 单一（双）非空货位

        //if (taskGroup == 999)
        //{
        //    pORcsLocations = pORcsLocations.Where(t => t.LocInputType == 2).ToList();
        //}
        //else
        //{
        //    pORcsLocations = pORcsLocations.Where(t => t.LocInputType == 1).ToList();
        //}
        pORcsLocations = pORcsLocations.Where(t => t.LocInputType == 2).ToList();
        var singleAllHalf = GetSingleLocationHalf(pORcsLocations, fork);
        //if (taskGroup == 999)
        //{
        //    // 单一 （单）无配对(空)
        //    LocationInfo locationInfo = singleAllHalf.Where(t => t.IsSingle == true && t.LocInputType == 2).FirstOrDefault();//查询单胎库位 LocTireType ==2  20250724
        //    if (locationInfo != null)
        //    {
        //        return locationInfo;
        //    }

        //}
        if (pORcsLocations.Count == 0)
        {
            return null;
        }

    
       // [双：（有货，空）]
            var have = singleAllHalf.Where(t => t.IsSingle == false && t.MaterialId == materialId &&  t.LocInputType == 1).FirstOrDefault();//查询单胎库位 LocTireType ==1   20250724
        if (have != null)
        {
            //lsq 查找空货位
            var emptyHave = pORcsLocations.Where(x => x.GroupId == have.GroupId & x.Id != have.Id).FirstOrDefault();
            if (emptyHave is not null)
            {

                return emptyHave;
            }
        }

        //// 单一 （单）无配对(空)
        //have = singleAllHalf.Where(t => t.IsSingle == true  && t.LocInputType ==2).FirstOrDefault();//查询单胎库位 LocTireType ==1  20250724
        //if (have != null)
        //{
        //    return have;
        //}

        // 双空货位[双（空，空）]
        have = GetDoubleLocation(pORcsLocations).Where(t => t.GroupIndex == fork.Index).FirstOrDefault();
        if (have != null)
        {

            // 有双库位
            return have;
        }

        // 物料不相同（双）
        have = singleAllHalf.Where(t => t.IsSingle == false).FirstOrDefault();
        var groupId = have?.GroupId;
        var haveId = have?.Id;
        //lsq
        var emptyHavem = pORcsLocations.Where(x => x.GroupId == groupId & x.Id != haveId).FirstOrDefault();

        return emptyHavem;
    }




    public List<LocationInfo> GetDoubleLocation(List<LocationInfo> pORcsLocations)
    {
        var ids = pORcsLocations
        .GroupBy(t => t.GroupId)
        .Select(t => new { GroupId = t.Key, Count = t.Count() })
        .ToList().Where(t => t.Count == 2).Select(t => t.GroupId).ToList();

        var result = pORcsLocations.Where(t => ids.Contains(t.GroupId)).OrderBy(t => t.RelateScore).ThenBy(t => t.GroupId).ToList();
        return result;
    }

    public List<PORcsLocation> GetDoubleRcsLocation(List<PORcsLocation> locations)
    {
        var ids = locations
        .GroupBy(t => t.GroupId)
        .Select(t => new { GroupId = t.Key, Count = t.Count() })
        .ToList().Where(t => t.Count == 2).Select(t => t.GroupId).ToList();

        var result = locations.Where(t => ids.Contains(t.GroupId)).OrderBy(t => t.RelateScore).ThenBy(t => t.GroupId).Select(t => new PORcsLocation()
        {
            Id = t.Id,
            LocCode = t.LocCode,
            LocName = t.LocName,
            PlcCode = t.PlcCode,
            LocType = t.LocType,
            GroupId = t.GroupId,
            GroupIndex = t.GroupIndex,
            AxisX = t.AxisX,
            AxisY = t.AxisY,
            AxisZ = t.AxisZ,
            AxisT = t.AxisT,
            NAxisX = t.NAxisX,
            NAxisY = t.NAxisY,
            NAxisZ = t.NAxisZ,
            NAxisT = t.NAxisT,
            LocHasSku = t.LocHasSku,
            LocHasSkuTime = t.LocHasSkuTime,
            TaskId = t.TaskId,
            TaskOccupy = t.TaskOccupy,
            TaskOccupyTime = t.TaskOccupyTime,
            LocEnable = t.LocEnable,
            InEnable = t.InEnable,
            OutEnable = t.OutEnable,
            MaterialId = t.MaterialId,
            ProductCode = t.ProductCode,
            MdTime = t.MdTime,
            ErrOutEmpty = t.ErrOutEmpty,
            ErrInHas = t.ErrInHas,
            UpdateTime = t.UpdateTime,
            UseFlag = t.UseFlag,
            LocHeight = t.LocHeight,
            LocMinOutsize = t.LocMinOutsize,
            LocMaxOutsize = t.LocMaxOutsize,
            LocTireType = t.LocTireType,
            RelateScore = t.RelateScore,
            CuringGroup = t.CuringGroup,
            CrnId = t.CrnId,
            LocInputType = t.LocInputType
        })
            .ToList();
        return result;
    }

    public (LocationInfo Loc1, LocationInfo Loc2) GetTagertDoubleLoc(List<LocationInfo> pORcsLocations,
      long? materialId1,
      long? materialId2, CrnForkInfo fork1, CrnForkInfo fork2, int? groupId)
    {
        //List<LocationInfo> data = null;
        //if (groupId != 999)
        //{
        //    data = GetDoubleLocation(pORcsLocations);
        //    var group = data.FirstOrDefault();
        //    if (group != null)
        //    {
        //        var have = data.Where(t => t.GroupId == group.GroupId).ToList();
        //        //WriteLog($"##############################查找货位1__{materialId1}：{group.GroupId},{have.ToJson()}", true);
        //        return (have.Where(t => t.GroupIndex == 1).FirstOrDefault(), have.Where(t => t.GroupIndex == 2).FirstOrDefault());
        //    }
        //}
        //if (groupId == 999)
        //{
        //    pORcsLocations = pORcsLocations.Where(t => t.LocInputType == 2).ToList();
        //}
        //else 
        //{
        //    pORcsLocations = pORcsLocations.Where(t => t.IsSingle == false &&  t.LocInputType ==1).ToList();
        //    var data = GetDoubleLocation(pORcsLocations);

        //    var group = data.FirstOrDefault();
        //    if (group != null)
        //    {
        //        var have = data.Where(t => t.GroupId == group.GroupId).ToList();
        //        //WriteLog($"##############################查找货位1__{materialId1}：{group.GroupId},{have.ToJson()}", true);
        //        return (have.Where(t => t.GroupIndex == 1).FirstOrDefault(), have.Where(t => t.GroupIndex == 2).FirstOrDefault());
        //    }

        //}
        if (groupId == 999) {
            WriteLog("配对胎不找单库位",true);
            return (null,null);
        }

        pORcsLocations = pORcsLocations.Where(t => t.IsSingle == false && t.LocInputType == 1).ToList();
        var data = GetDoubleLocation(pORcsLocations);

        var group = data.FirstOrDefault();
        if (group != null)
        {
            var have = data.Where(t => t.GroupId == group.GroupId).ToList();
            //WriteLog($"##############################查找货位1__{materialId1}：{group.GroupId},{have.ToJson()}", true);
            return (have.Where(t => t.GroupIndex == 1).FirstOrDefault(), have.Where(t => t.GroupIndex == 2).FirstOrDefault());
        }

        // singleAllHalf 有货单货位
        var singleAllHalf = GetSingleLocationHalf(pORcsLocations, fork1);
        if (singleAllHalf.Count < 1)
        {
            //TODO 【暂时反回null】单一空位小于 2 默认运输一个还是，都停止？
            return (null, null);
        }

        // 有胎货位
        var have1 = singleAllHalf.Where(t => t.IsSingle == false && t.MaterialId == materialId1).FirstOrDefault();
        if (have1 == null)
        {

            have1 = singleAllHalf.Where(t => t.IsSingle == true && t.LocInputType==2).FirstOrDefault();
            if (have1 == null)
            {
                // 单库位有配对
                have1 = singleAllHalf.Where(t => t.IsSingle == false &&  t.LocInputType == 1).FirstOrDefault();
            }
        }
        if (have1.IsSingle == false)
        {
            // lsq 空货位
            have1 = pORcsLocations.Where(x => x.GroupId == have1.GroupId && x.Id != have1.Id).FirstOrDefault();
        }

        singleAllHalf = GetSingleLocationHalf(pORcsLocations, fork2);
        if (singleAllHalf.Count < 1)
        {

            return (null, null);
        }
        var flag = false;
        var have2 = singleAllHalf.Where(t => t.IsSingle == flag && t.MaterialId == materialId2 && t.GroupId != have1.GroupId).FirstOrDefault();

        if (have2 == null)
        {
            have2 = singleAllHalf.Where(t => t.IsSingle == true && t.GroupId != have1.GroupId).FirstOrDefault();

            if (have2 == null)
            {
                // 单库位有配对
                have2 = singleAllHalf.Where(t => t.IsSingle == false && t.GroupId != have1.GroupId).FirstOrDefault();
                if (have2 == null)
                {
                    // WriteLog($"##############################查找货位4__{materialId1}_{fork2.Fork}：{have1?.Id},{group?.GroupId}——{pORcsLocations.ToJson()}", true);

                    return (null, null);
                }
            }
        }
        if (have2.IsSingle == false)
        {
            //lsq
            have2 = pORcsLocations.Where(x => x.GroupId == have2.GroupId && x.Id != have2.Id).FirstOrDefault();
        }

        return (have1, have2);
    }


    public (LocationInfo Loc1, LocationInfo Loc2) GetTagertDoubleLocV1(List<LocationInfo> pORcsLocations,
        long? materialId1,
        long? materialId2, CrnForkInfo fork1, CrnForkInfo fork2)
    {

        // 双空货位
        var data = GetDoubleLocation(pORcsLocations);
        var groupTask = data.FirstOrDefault();
        if (groupTask != null)
        {
            var have = data.Where(t => t.GroupId == groupTask.GroupId).ToList();
            return (have.Where(t => t.GroupIndex == 1).FirstOrDefault(), have.Where(t => t.GroupIndex == 2).FirstOrDefault());
        }



        // singleAllHalf 有货单货位
        var singleAllHalf = GetSingleLocationHalf(pORcsLocations, fork1);
        if (singleAllHalf.Count < 1)
        {
            //OLDTODO【暂时反回null】单一空位小于 2 默认运输一个还是，都停止？
            return (null, null);
        }


        // 有胎货位[双货位，物料匹配]
        var have1 = singleAllHalf.Where(t => t.IsSingle == false && t.MaterialId == materialId1).FirstOrDefault();
        if (have1 is not null)
        {
            // lsq 空货位 [双货位，物料匹配]
            have1 = pORcsLocations.Where(x => x.GroupId == have1.GroupId && x.Id != have1.Id).FirstOrDefault();
        }
        else
        {
            // 单的 空库位
            have1 = singleAllHalf.Where(t => t.IsSingle == true).FirstOrDefault();
            if (have1 == null)
            {
                // 单库位有配对[双货位，不匹配物料]
                have1 = singleAllHalf.Where(t => t.IsSingle == false).FirstOrDefault();
                have1 = pORcsLocations.Where(x => x.GroupId == have1.GroupId && x.Id != have1.Id).FirstOrDefault();
            }
        }




        singleAllHalf = GetSingleLocationHalf(pORcsLocations, fork2);
        if (singleAllHalf.Count < 1)
        {

            return (null, null);
        }

        var have2 = singleAllHalf.Where(t => t.IsSingle == false && t.MaterialId == materialId2 && t.GroupId != have1?.GroupId).FirstOrDefault();
        if (have2 is not null)
        {

            //lsq
            have2 = pORcsLocations.Where(x => x.GroupId == have2.GroupId && x.Id != have2.Id).FirstOrDefault();
        }
        else
        {

            have2 = singleAllHalf.Where(t => t.IsSingle == true && t.GroupId != have1?.GroupId).FirstOrDefault();

            if (have2 == null)
            {

                // 单库位有配对
                have2 = singleAllHalf.Where(t => t.IsSingle == false && t.GroupId != have1?.GroupId).FirstOrDefault();

                have2 = pORcsLocations.Where(x => x.GroupId == have2.GroupId && x.Id != have2.Id).FirstOrDefault();
                if (have2 == null)
                {
                    return (null, null);
                }
            }
        }



        return (have1, have2);
    }

    public List<PORcsLocation> GetLocationsByLocIds(List<long?> ids)
    {
        var db = Db.Default;

        var result = GetAllLocations().Where(t => ids.Contains(t.Id)).ToList();
        return result;
    }
    public List<PORcsLocation> GetCuringLocationsByLocIds(List<long?> ids)
    {
        var db = Db.Default;
        var result = GetAllCuringLocations();// .Where(t => ids.Contains(t.Id)).ToList();
        result = result.Join(ids, f => f.Id, s => s, (f, s) => f).Select(t => new PORcsLocation()
        {
            Id = t.Id,
            LocCode = t.LocCode,
            LocName = t.LocName,
            PlcCode = t.PlcCode,
            LocType = t.LocType,
            GroupId = t.GroupId,
            GroupIndex = t.GroupIndex,
            AxisX = t.AxisX,
            AxisY = t.AxisY,
            AxisZ = t.AxisZ,
            AxisT = t.AxisT,
            NAxisX = t.NAxisX,
            NAxisY = t.NAxisY,
            NAxisZ = t.NAxisZ,
            NAxisT = t.NAxisT,
            LocHasSku = t.LocHasSku,
            LocHasSkuTime = t.LocHasSkuTime,
            TaskId = t.TaskId,
            TaskOccupy = t.TaskOccupy,
            TaskOccupyTime = t.TaskOccupyTime,
            LocEnable = t.LocEnable,
            InEnable = t.InEnable,
            OutEnable = t.OutEnable,
            MaterialId = t.MaterialId,
            ProductCode = t.ProductCode,
            MdTime = t.MdTime,
            ErrOutEmpty = t.ErrOutEmpty,
            ErrInHas = t.ErrInHas,
            UpdateTime = t.UpdateTime,
            UseFlag = t.UseFlag,
            LocHeight = t.LocHeight,
            LocMinOutsize = t.LocMinOutsize,
            LocMaxOutsize = t.LocMaxOutsize,
            LocTireType = t.LocTireType,
            RelateScore = t.RelateScore,
            CuringGroup = t.CuringGroup,
            CrnId = t.CrnId,
            LocInputType = t.LocInputType
        })
            .ToList();
        return result;
    }

    public PORcsLocation GetLocTaskIdByLocIdAndTaskId(long taskId, long locId)
    {
        var db = Db.Default;

        var result = db.RcsLocations
            .Where(t => t.UseFlag == 1 && t.TaskId == taskId && t.Id == locId).FirstOrDefault();

        return result;
    }

    public int ClearLocationHasTaskByTaskId(long taskId)
    {
        var db = Db.Default;

        var dateTime = System.DateTime.Now;

        var locs = db.RcsLocations
            .Where(t => t.UseFlag == 1 && t.TaskId == taskId).ToList();

        foreach (var loc in locs)
        {
            loc.TaskId = null;
            loc.TaskOccupy = 0;
            loc.LocHasSku = 0;
            loc.UpdateTime = dateTime;
            loc.LocHasSkuTime = null;
            loc.MaterialId = null;
            loc.TaskOccupyTime = null;
            loc.MdTime = null;
        }
        db.SaveChanges();
        return 1;

        //var result = db.RcsLocations
        //    .Where(t => t.UseFlag == 1 && t.TaskId == taskId)
        //    .Update(new PORcsLocation
        //    {
        //        TaskId = null,
        //        TaskOccupy = 0,
        //        LocHasSku = 0,
        //        UpdateTime = dateTime,
        //        LocHasSkuTime = null,
        //        MaterialId = null,
        //        TaskOccupyTime = null,
        //        MdTime = null
        //    });
        //db.SaveChanges();

        //return result;
    }


    public List<PORcsLocation> GetTireTypeLocations(int tireType)
    {
        var db = Db.Default;
        var result = GetAllLocations()
            .Where(t => t.InEnable == 1 && t.LocTireType == tireType)
            .Select(t => new PORcsLocation()
            {
                Id = t.Id,
                LocCode = t.LocCode,
                LocName = t.LocName,
                PlcCode = t.PlcCode,
                LocType = t.LocType,
                GroupId = t.GroupId,
                GroupIndex = t.GroupIndex,
                AxisX = t.AxisX,
                AxisY = t.AxisY,
                AxisZ = t.AxisZ,
                AxisT = t.AxisT,
                NAxisX = t.NAxisX,
                NAxisY = t.NAxisY,
                NAxisZ = t.NAxisZ,
                NAxisT = t.NAxisT,
                LocHasSku = t.LocHasSku,
                LocHasSkuTime = t.LocHasSkuTime,
                TaskId = t.TaskId,
                TaskOccupy = t.TaskOccupy,
                TaskOccupyTime = t.TaskOccupyTime,
                LocEnable = t.LocEnable,
                InEnable = t.InEnable,
                OutEnable = t.OutEnable,
                MaterialId = t.MaterialId,
                ProductCode = t.ProductCode,
                MdTime = t.MdTime,
                ErrOutEmpty = t.ErrOutEmpty,
                ErrInHas = t.ErrInHas,
                UpdateTime = t.UpdateTime,
                UseFlag = t.UseFlag,
                LocHeight = t.LocHeight,
                LocMinOutsize = t.LocMinOutsize,
                LocMaxOutsize = t.LocMaxOutsize,
                LocTireType = t.LocTireType,
                RelateScore = t.RelateScore,
                CuringGroup = t.CuringGroup,
                CrnId = t.CrnId,
                LocInputType = t.LocInputType
            })
            .ToList();
        return result;
    }

    public int UpdateLocationMateiralId(long locId, long mateiralId)
    {
        var db = Db.Default;

        var dateTime = DateTime.Now;
        var result = db.RcsLocations
            .Where(t => t.Id == locId)
            .Update(new PORcsLocation
            {
                UpdateTime = dateTime,
                MaterialId = mateiralId,
            });

        return db.SaveChanges();
    }
    public int UpdateLocTaskId(long id, string productCode, long taskId, string remark)
    {
        var db = Db.Default;

        var result = db.RcsLocations
            .Where(t => t.Id == id).Update(new PORcsLocation
            {
                TaskId = taskId,
                TaskOccupy = 1,
                TaskOccupyTime = DateTime.Now,
                Remarks = remark
            });
        return db.SaveChanges();
    }

    public int UpdateTestInEnableRemark(long id, string remark)
    {
        var db = Db.Default;
        var result = db.RcsLocations.Where(t => t.Id == id).Update(new PORcsLocation
        {
            UpdateTime = DateTime.Now,
            InEnable = 0,
            Remarks = remark,
        });
        return result;
    }
    public int UpdateCrnLocEnableRemark(string productCode, string remark)
    {
        var db = Db.Default;
        var skuId = _ProdProduct.GetSkuIdByCode(productCode);

        var locIds = _WcsLocSku.GetWcsLocSkusBySkuId(skuId).Select(t => t.LocId).ToList();

        var dateTime = DateTime.Now;
        var result = db.RcsLocations
    .Where(t => locIds.Contains(t.Id) && t.LocType == (int)EnumLocType.Location)
    .Update(new PORcsLocation
    {
        UpdateTime = dateTime,
        LocEnable = 0,
        Remarks = remark
    });

        return db.SaveChanges();
    }

    public int UpdateLocationProductCode(long locId, string productCode)
    {
        var db = Db.Default;
        var product = _ProdProduct.GetProductByCode(productCode);
        if (product == null)
        {
            return 0;
        }
        var materialId = product.MaterialId;
        var dateTime = System.DateTime.Now;
        var result = db.RcsLocations
            .Where(t => t.Id == locId)
            .Update(new PORcsLocation
            {
                UpdateTime = dateTime,
                LocHasSku = 1,
                LocHasSkuTime = DateTime.Now,
                MaterialId = materialId,
                ProductCode = productCode,
            });

        return db.SaveChanges();
    }

    public long GetWarehouseByLocationID(long locId)
    {
        var db = Db.Default;
        var locEquipId = db.WcsEquipLocHolds.Where(t => t.LocId == locId).FirstOrDefault().EquipId ?? 0;
        var result = db.RcsEquipCrns.Where(t => t.Id == locEquipId).FirstOrDefault().WarehourseId ?? 0;
        return result;
    }
}
